dhcpv6c: fix illegal DHCPV6_OPT_FQDN
authorPaul Donald <[email protected]>
Wed, 1 Oct 2025 21:38:13 +0000 (23:38 +0200)
committerÁlvaro Fernández Rojas <[email protected]>
Fri, 17 Oct 2025 17:20:01 +0000 (19:20 +0200)
Some message types e.g. DHCPV6_MSG_INFO_REQ contained
DHCPV6_CLIENT_FQDN (39) which is illegal. See Client FQDN RFC4704:

https://www.rfc-editor.org/rfc/rfc4704#section-5

   A client MUST only include the Client FQDN option in SOLICIT,
   REQUEST, RENEW, or REBIND messages.

https://www.rfc-editor.org/rfc/rfc4704#section-6

   Servers MUST only include a Client FQDN option in ADVERTISE and REPLY
   messages...

Do not send it unless the message type is appropriate.

Signed-off-by: Paul Donald <[email protected]>
Link: https://github.com/openwrt/odhcp6c/pull/100
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
src/dhcpv6.c

index 5bf1ff46ec85657aafebd1c0ee3e27fb0ba8817c..28a2de29f21c928946da65ba6e8a5fd73311e40a 100644 (file)
@@ -582,8 +582,32 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs)
                        !(client_options & DHCPV6_ACCEPT_RECONFIGURE))
                iov[IOV_RECONF_ACCEPT].iov_len = 0;
 
-       if (!(client_options & DHCPV6_CLIENT_FQDN))
+       if (!(client_options & DHCPV6_CLIENT_FQDN)) {
                iov[IOV_FQDN].iov_len = 0;
+       } else {
+               switch (type) {
+               /*  rfc4704 §5
+                       A client MUST only include the Client FQDN option in SOLICIT,
+                       REQUEST, RENEW, or REBIND messages.
+               */
+               case DHCPV6_MSG_SOLICIT:
+               case DHCPV6_MSG_REQUEST:
+               case DHCPV6_MSG_RENEW:
+               case DHCPV6_MSG_REBIND:
+               /*  rfc4704 §6
+                       Servers MUST only include a Client FQDN option in ADVERTISE and REPLY
+                       messages...
+               case DHCPV6_MSG_ADVERT:
+               case DHCPV6_MSG_REPLY:
+               */
+                       /* leave FQDN as-is */
+                   break;
+               default:
+                       /* remaining MSG types cannot contain client FQDN */
+                       iov[IOV_FQDN].iov_len = 0;
+                   break;
+               }
+       }
 
        struct sockaddr_in6 srv = {AF_INET6, htons(DHCPV6_SERVER_PORT),
                0, ALL_DHCPV6_RELAYS, ifindex};